package com.shanxia.im.handler;

import com.shanxia.codec.ProtocolDataBase;
import com.shanxia.codec.cmd.Cmd105;
import com.shanxia.codec.cmd.Cmd106;
import com.shanxia.im.push.IMMessagePusher;
import com.shanxia.im.sdk.server.constant.IMConstant;
import com.shanxia.im.sdk.server.handler.IMRequestHandler;
import com.shanxia.im.sdk.server.model.IMSession;
import com.shanxia.im.service.IMSessionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

/*
 * 充电桩签到 账号 绑定
 * 
 */
@Component
public class BindHandler implements IMRequestHandler {

	private final Logger logger = LoggerFactory.getLogger(BindHandler.class);

	@Resource
	private IMSessionService imSessionService;

	@Value("${server.host}")
	private String host;
	
	@Resource
	private IMMessagePusher defaultMessagePusher;
	
	@Override
	public void process(IMSession newSession, ProtocolDataBase protocolDataBase) {

		if(protocolDataBase instanceof Cmd106){
			Cmd106 request = (Cmd106)protocolDataBase;
			Cmd105 reply = new Cmd105();
			reply.setCmd(request.getCmd());
			reply.setRandomReply(request.getRandomNumber());
			reply.setLoginVerify(0);
			reply.setEncryptionSign(0);
			reply.setRsaModeNum("0");
			reply.setRsaSecretKey(0);
			LocalDateTime localDateTime = LocalDateTime.now();
			DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
			reply.setStandardTime(localDateTime.format(dtf2));
			try {

				String account = request.getSn();
				newSession.setHost(host);
				newSession.setAccount(account);
				newSession.setSign(request.getSign());
				newSession.setSoftwareVersion(request.getSoftwareVer());
				newSession.setDeviceId(request.getSn());
				newSession.setProjectType(request.getProjectType());
				newSession.setStartNum(request.getStartNum());
				newSession.setUploadMode(request.getUploadMode());
				newSession.setSignInterval(request.getSignInterval());
				newSession.setInnerVariate(request.getInnerVariate());
				newSession.setPileNum(request.getPileNum());
				newSession.setHeartbeatPeriod(request.getHeartbeatPeriod());
				newSession.setOvertimeCount(request.getOvertimeCount());
				newSession.setChargingRecordCount(request.getChargingRecordCount());
				// TODO 如果当桩上报的“当前充电桩系统时间”误差大于5秒时，建议后台下发CMD=3中的同步时间命令，对充电桩时间进行同步。
				newSession.setCurrentTime(request.getCurrentTime());
				newSession.setRandomNumber(request.getRandomNumber());
				newSession.setProtocolVer(request.getProtocolVer());
				newSession.setWhitelistVer(request.getWhitelistVer());
				newSession.setDeviceType(request.getDeviceType());

				newSession.setBindTime(System.currentTimeMillis());
				/*
				 * 由于客户端断线服务端可能会无法获知的情况，客户端重连时，需要关闭旧的连接
				 */
				IMSession oldSession = imSessionService.get(account);

				/*
				 * 如果是账号已经在另一台终端登录。则让另一个终端下线
				 */
				if (oldSession != null && fromOtherDevice(newSession,oldSession) && oldSession.isConnected()) {
					sendForceOfflineMessage(oldSession, account);
				}

				/*
				 * 有可能是同一个设备重复连接，则关闭旧的链接，这种情况一般是客户端断网，联网又重新链接上来，之前的旧链接没有来得及通过心跳机制关闭，在这里手动关闭
				 * 条件1，连接来自是同一个设备
				 * 条件2.2个连接都是同一台服务器
				 */
				if (oldSession != null && !fromOtherDevice(newSession,oldSession) && Objects.equals(oldSession.getHost(),host)) {
					closeQuietly(oldSession);
				}

				imSessionService.save(newSession);

			} catch (Exception exception) {
				//reply.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
				logger.error("Bind has error",exception);
			}

			newSession.write(reply);
		}

	}

	private boolean fromOtherDevice(IMSession oldSession , IMSession newSession) {
			
			return !Objects.equals(oldSession.getDeviceId(), newSession.getDeviceId());
	}
	 
	private void sendForceOfflineMessage(IMSession oldSession, String account) {

		/*Message msg = new Message();
		msg.setAction(IMConstant.MessageAction.ACTION_OFFLINE);
		msg.setReceiver(account);
		msg.setSender("system");
		//msg.setContent(deviceModel);
		msg.setId(System.currentTimeMillis());
		
		defaultMessagePusher.push(account, msg);*/
		
		closeQuietly(oldSession);

	}

	private void closeQuietly(IMSession oldSession) {
		if (oldSession.isConnected() && Objects.equals(host, oldSession.getHost())) {
			oldSession.setAttribute(IMConstant.KEY_QUIETLY_CLOSE,true);
			oldSession.closeOnFlush();
		}
	}

}
